/**
 * Created by xiaoz on 16/8/13.
 */

define(["utils","pageview","jquery"],function(utils,PageView,$){


    var isPrevent = false,wantToPreventHashChange=false;
    function PageViewManager(){

        var _this = this;
        this.global ={};
        this.isIE = utils.browserInfo().isIE;
        this.pages = {};
        this.isInit = true;
        this.curPageView = null;
        this.pagekeySeed = 0;

          this.isForward = false;
        this.seed = 1;

        this.isPrevent = false;
        this.$el =$("<div class='yy-root-view'></div>");
        this.$el.appendTo(document.body);
        window.onhashchange=function(){
            _this.hashChange();

        };

        var alertFallback = true;
        if (typeof console === "undefined" || typeof console.log === "undefined") {
          console = {};
          if (alertFallback) {
              console.log = function(msg) {
                  //  alert(msg);
              };
          } else {
              console.log = function() {};
          }
        }



        this.BodyClickCallBackDict={};
        $(document.body).bind("click",function(){
          for(var key in _this.BodyClickCallBackDict){
            try{
              _this.BodyClickCallBackDict[key]();
            }catch(e){
              continue;
            }
          }
        });


        if (!Array.prototype.indexOf){
            Array.prototype.indexOf = function(elt /*, from*/){
            var len = this.length >>> 0;
            var from = Number(arguments[1]) || 0;
            from = (from < 0)? Math.ceil(from): Math.floor(from);
            if (from < 0)
              from += len;
            for (; from < len; from++)
            {
              if (from in this &&
                  this[from] === elt)
                return from;
            }
            return -1;
          };
        }

        this.windowResizeCallBack = {};

        if(utils.isNeedReLayout()){
          var resizeID = null;
          $(window).bind("resize",function(){
            if(resizeID){
              window.clearTimeout(resizeID);
            }
            resizeID = window.setTimeout(function(){
              for(var key in _this.windowResizeCallBack){
                try{
                  _this.windowResizeCallBack[key]();
                }catch(e){
                  continue;
                }
              }
            },300);
          });
        }



    }

    PageViewManager.prototype = {
        regeistBodyClick:function(id,callback){
          // if(this.BodyClickCallBackDict[id]){
            this.seed+=1;
            id = id+"$$"+this.seed;
          // }
          // console.log(id);

          this.BodyClickCallBackDict[id]=callback;
        },
        regeistWindowResize:function(id,callback){
          this.windowResizeCallBack[id]=callback;
        },


        triggerBodyClickWithoutSelf:function(com){
          var _this = this;
          for(var key in _this.BodyClickCallBackDict){
            if(com){
              if(com.id===key){
                continue;
              }
              var idArr = com.id.split("$$");
              if(idArr[0]===key){
                continue;
              }
              var keyArr = key.split("_");
              if(keyArr.length>1){
                var lastKey = keyArr[keyArr.length-1];
                if(lastKey==="sildepage"){
                  continue;
                }
              }
            }
            try{
              _this.BodyClickCallBackDict[key]();
            }catch(e){
              continue;
            }
          }
        },
        cancelBodyClick:function(com_id){
          delete this.BodyClickCallBackDict[com_id];
        },
        trigger:function(eventname){
          this.eventHasDone[eventname]=true;
          this.eventPool[eventname] = this.eventPool[eventname]||[];
          for(var i=0,j=this.eventPool[eventname].length;i<j;i++){
            this.eventPool[eventname][i]();
          }
          delete this.eventPool[eventname];
        },
        eventPool:{},
        eventHasDone:{},
        bindOnce:function(eventname,callBack){
          if(this.eventHasDone[eventname]===true){
            callBack();
            return;
          }
          this.eventPool[eventname] = this.eventPool[eventname]||[];
          this.eventPool[eventname].push(callBack);
        },
        start:function(config){
            utils.appConfig = config;
            this.appConfig = config;
            utils.customerComponents = config.customerComponents||{};
            this.config = config;
            var routeNames = this.getPageNameArrFromUrl();
            var toPage = routeNames[0];
            if(!toPage){
                this.replaceGo(config.root,this.getParamsFromUrl(),true);
            }else{
                this.hashChange();
            }
        },
        showPageKeyDict:{},

        regeistShowPageInRouter:function(pageKey){
          this.showPageKeyDict[pageKey] = true;
        },

        showBackLayer:function(cb){
          if(!this.bkLayer ){
            this.bkLayer = $("<div class='yy-bk-layer displaynone'></div>");
            this.bkLayer.appendTo(document.body);
            this.bkLayer.bind("click",function(e){
                cb();
            });

          }
          this.bkLayer.removeClass("displaynone");
        },
        hideBackLayer:function(){
          if(this.bkLayer ){
            this.bkLayer.addClass("displaynone");
          }
        },
        preventHasChange:function(){
          wantToPreventHashChange = true;
        },
        hashChange:function(){
            var _this = this;
            if(isPrevent){
              isPrevent = false;
              return ;
            }
            if(wantToPreventHashChange===true){
              wantToPreventHashChange=false;
              return;
            }

          var routes = this.getPageNameArrFromUrl();
          var copyRoutes = utils.copy(routes);

           if (this.config.routerChange) {
              var routeChangeRe = this.config.routerChange({
                  curRoutes: routes,
                  beforeRouter: this.beforeRouter
              });
              if (routeChangeRe === false) {
                  isPrevent = true;
                  if(this.isForward){
                    window.history.go(-1);
                  }else{
                    window.history.go(1);
                  }
                  return;
              }
          }

          pageKey = routes.shift();

          this.isForward = false;

          this.beforeRouter = copyRoutes;



          var pageInstance = this.pages[pageKey];
          if(pageInstance){
            if(_this.curPageView){
             _this.curPageView.hideCurShowPage();
             _this.curPageView.$el.addClass("displaynone");
             _this.curPageView = pageInstance;
            }

            pageInstance.removeClass("displaynone");
            pageInstance.hashChange(routes);
            var ResumeMethod = pageInstance.plugin.onPageResume;
            if(ResumeMethod){
              ResumeMethod.call(pageInstance.plugin,pageInstance,{});

            }
            return;
          }


          _this.getPageConfigByPageKey(pageKey,function(pageConfig){
            // 实例化页面对象
            pageConfig.pagecontainer = _this;
            pageInstance =  _this.createPageView(pageConfig);
            // 保存对象
            _this.pages[pageKey] = pageInstance;
            // 传递路由
            pageInstance.hashChange(routes);
            // 渲染页面
            _this.$el.append(pageInstance.$el);
            if(_this.curPageView){
             _this.curPageView.hideCurShowPage();
             _this.curPageView.$el.addClass("displaynone");
             _this.curPageView  = pageInstance;
            }

          },function(e){
            if(error){
              error(fromPageInstance);
            }
          });
       },
       createPageView:function(pageConfig){
          return new PageView(pageConfig);
        },
        getPageNameArrFromUrl:function(){
            //构造路由对象，截取url中#后的地址
            var nameArr = window.location.hash.split("#");
            // if(nameArr.length!=2){
            //     return [];
            // }

            var s = nameArr[1];
            if(s===undefined){
              return [];
            }
            var sArr = s.split("?");
            var pagenames = sArr[0];
            if(!pagenames){
              return [];
            }
            return pagenames.split("/");
        },
        getParamsStrFromUrl:function(){
          var Arr = window.location.href.split("?");
          var str = Arr[Arr.length-1];
          if(!str){
            return null;
          }
          var str_arr = str.split("#");
          if(str_arr.length>=3){
            return str_arr.join("");
          }
          return str_arr[0];
        },
        getParamsFromUrl:function(){
            var paraStr = this.getParamsStrFromUrl();
            if (!paraStr) {
                return null;
            }
            var re = {};
            var paramsArr = paraStr.split("&");
            for (var i = 0, j = paramsArr.length; i < j; i++) {
                var key_value_arr = paramsArr[i].split("=");
                if (key_value_arr.length == 2) {
                    re = re || {};
                    re[key_value_arr[0]] = key_value_arr[1];
                } else if (key_value_arr.length > 2) {
                    var pk = key_value_arr.shift();
                    re[pk] = key_value_arr.join("=");
                }
            }
            return re;
       },
       goBack:function(){
           this.isForward = false;
           window.history.go(-1);
       },
        go:function(pageKey,params){
            this.isForward = true;
            isPrevent = false;
            params = params||{};
            var paramsArr = [];
            for(var key in params){
                paramsArr.push(key+"="+params[key]);
            }
            pageKey = this._getUniquePageKey(pageKey);
            if(paramsArr.length>0){
                location.hash = pageKey+"?"+paramsArr.join("&");
            }else{
                location.hash = pageKey;
            }
        },
        replaceGo: function(pageKey, params,isClearParams) {
        this.isForward = true;
        isPrevent = false;
        if (this.isInit) {
            this.rootPageKey = pageKey;

        } else {

        }
        params = params || {};
        var paramsArr = [];
        for (var key in params) {
            paramsArr.push(key + "=" + params[key]);
        }
        pageKey = this._getUniquePageKey(pageKey);
        isReplaceGo = true;
        if(isClearParams===true){
            if (paramsArr.length > 0) {
                location.replace(location.href.split("?")[0] + '#' + pageKey + "?" +  paramsArr.join("&"));
            } else {
                location.replace(location.href.split("?")[0] + '#' + pageKey);
            }
        }else{
            if (paramsArr.length > 0) {
                location.replace(location.href.split("#")[0] + '#' + pageKey + "?" +  paramsArr.join("&"));
            } else {
                location.replace(location.href.split("#")[0] + '#' + pageKey);
            }
        }


    },

        _getUniquePageKey:function(pagekey){
            var hasSameKeyInStack = false;
            for(var key in this.pages){
                var key_arr = key.split("$$");
                if(key_arr[0]==pagekey){
                    this.pagekeySeed += 1;
                    hasSameKeyInStack = true;
                    break;
                }
            }
            return hasSameKeyInStack?(pagekey+"$$"+this.pagekeySeed):pagekey;
        },
        _getPageConfigSuccess:function(pageKey,pageConfig,success){
          pageConfig = utils.copy(pageConfig);
          pageConfig.type= "pageview";
          pageConfig.pageKey = pageKey;
          pageConfig.$$params = this.getParamsFromUrl();
          pageConfig.$$pageManager = this;
          success(pageConfig);
        },

        //通过页面id获取页面config
        // pageKey 页面id，url中获取
        getPageConfigByPageKey:function(pageKey,success,error){
            var _this = this;
            var page_path = "./pages/"+pageKey.split("$$")[0];
            //先从缓存中获取页面配置
            var _pageConfig = utils.getPageConfigByPagePath(page_path);
            if(_pageConfig){
              this._getPageConfigSuccess(pageKey,_pageConfig,success);
              return;
            }
            // var randomPath = page_path+".js?t="+(new Date()).valueOf();//避免网络断开请求失败后 无论是否再次联网都失败
            require([page_path],function(pageConfig){
              //保存页面配置
              pageConfig = utils.setPageConfigByPagePath(page_path,pageConfig);
              _this._getPageConfigSuccess(pageKey,pageConfig,success);
            },function(e){
              console.error(e);
              if(error){
                error(pageKey);
              }
            });
        }

    };
    return new PageViewManager();
});
